home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-06-25 | 29.7 KB | 1,064 lines | [TEXT/CWIE] |
- /*
- Dimmer2Effect.c - a sample QuickTime video effect.
-
- This effect uses a single source as input, and renders that source with
- a dim value that starts at full on, and ramps to full off. This isn't very
- useful as a real effect, but shows instead how to create an effect.
-
- READ THIS PARAGRAPH BEFORE DOING ANYTHING ELSE IN THIS FILE:
- To find things to change to implement your effect, seach for *** CHANGE ***.
- Code that will require modification is bracketted by CHANGE/END CHANGE.
-
- There are eleven places to change code, and one place where you write new
- code that implements your actual effect. MAKE SURE YOU LOOK AT ALL OF THEM.
-
- *IMPORTANT*
-
- You MUST also ensure that the Effect.r file is kept in sync with this code.
- In particular it is very important that you update the 'atms' resource
- description so that the parameters of your effect are correctly described.
- Full details of the format of the 'atms' resource can be found in the Effects
- chapter of the QT 3.0 documentation
-
- ALSO PLEASE NOTE THAT THE LINK WARNING ABOUT THE COMPONENT DISPATCH ENTRY POINT
- NOT BEING A ROUTINE DESCRIPTOR IS NORMAL AND CAN BE IGNORED!
-
- written by Tom Dowdy and Dan Crow
- copyright © 1997-1998 Apple Computer, Inc.
- All rights reserved.
- */
-
-
- // --------------------------------------------------------------------------------------
- // INCLUDES
- // --------------------------------------------------------------------------------------
-
- #include <MacMemory.h>
- #include <Resources.h>
- #include <Quickdraw.h>
- #include <QDOffscreen.h>
- #include <OSUtils.h>
- #include <Errors.h>
- #include <FixMath.h>
- #include <Movies.h>
- #include <Endian.h>
- #include <ImageCodec.h>
-
- #include "EffectDefinitions.h"
-
- #if PRAGMA_STRUCT_ALIGN
- #pragma options align=mac68k
- #endif
-
- #include "EffectUtilities.h"
-
-
- // --------------------------------------------------------------------------------------
- // INTERNAL DEFINES
- // --------------------------------------------------------------------------------------
-
- // *** CHANGE *** This defines the number of frames that can be queued for
- // asynchronous rendering by this effect. The value 0 indicates the effect
- // runs synchronously.
- #define kMaxAsyncFrames 0
- // *** END CHANGE ***
-
- // *** CHANGE *** Change if your effect accepts multiple sources. This value
- // is the maximum number of sources this effect operates on.
- #define kMaxSources 2
- // *** END CHANGE ***
-
- // --------------------------------------------------------------------------------------
- // INTERNAL TYPEDEFS
- // --------------------------------------------------------------------------------------
-
- // Structure used to store inforation about each source
- typedef struct SourceRecord {
- CDSequenceDataSourcePtr src;
- void *srcBaseAddr;
- long srcRowBytes;
- } SourceRecord;
-
- // This is the structure used to store information for drawing a single frame of the effect
- typedef struct BlitGlobals {
- SourceRecord sources[kMaxSources]; // inputs
-
- void *dstBaseAddr; // output base address
- long dstRowBytes; // output row bytes
- long height; // output height
- long width; // output width
- short destDepth; // output depth
- OSType dstPixelFormat; // output pixel format
-
- // *** CHANGE *** Here is where we store values relating to a single frame
- // of the effect. These are the parameters to the effect, modified by the
- // percentage into the effect which we are.
-
- long direction;
- short dimValue; // dimming value, from 0 to 255
-
- long iIntegrity;
- UInt8* puiRandoms;
- UInt8* puiBrightnessRoll;
- UInt8* puiBRStart;
- UInt8* puiBREnd;
- // *** END CHANGE ***
- } BlitGlobals;
-
-
- // global data per instance. This holds data for the entire effect as it runs its course.
- typedef struct EffectGlobals
- {
- ComponentInstance self; // ourselves
- ComponentInstance target; // top of the calling chain
- ComponentInstance delegate; // if we can't handle an effect, this one can
-
- BlitGlobals blitter; // information for drawing the data
- OSType **wantedDestinationPixelTypeH;
-
- #if kMaxAsyncFrames > 0
- volatile short asyncCount; // number of outstanding frames we have
- #endif
-
- // parameter/source/dest seed tracking
- long initialized;
- long frameNumber;
- long virtualDuration;
- long majorSourceChangeSeed;
-
- TweenGlobals tweenGlobals;
-
- // *** CHANGE *** PLACE PARAMETERS FOR YOUR EFFECT HERE
-
- long direction; // direction of blit. 0 for dim to bright, 255 for bright to dim
-
- TweenContainerRecord percentage;
-
- // *** END CHANGE ***
- } EffectGlobals;
-
- // --------------------------------------------------------------------------------------
- // DISPATCHER
- // --------------------------------------------------------------------------------------
- /************************************************************************************
- * This is the main dispatcher for our codec. All calls from the codec manager
- * will come through here, with a unique selector and corresponding parameter block.
- *
- * This routine must be first in the code segment of the codec component.
- *
- * We use the normal dispatcher rather than the codec dispatcher as we need to
- * implement the extra effects routines on top of the codec ones.
- */
- /************************************************************************************/
- // Begin Dispatch Stuff
-
- // Used by Component Dispatch Helper to call our routines
- #define CALLCOMPONENT_BASENAME() EffectsFrame
- #define CALLCOMPONENT_GLOBALS() EffectGlobals * storage
-
- // Used by Type's .k.h to create prototypes for our routines
- #define IMAGECODEC_BASENAME() CALLCOMPONENT_BASENAME()
- #define IMAGECODEC_GLOBALS() CALLCOMPONENT_GLOBALS()
-
- // Used by SubType's .k.h to create prototypes for our routines
- #define IMAGECODECEFFECT_BASENAME() CALLCOMPONENT_BASENAME()
- #define IMAGECODECEFFECT_GLOBALS() CALLCOMPONENT_GLOBALS()
-
- // Other defines for Component Dispatch Helper
- #define COMPONENT_DISPATCH_FILE "EffectDispatch.h" // describes what to dispatch
- #define GET_DELEGATE_COMPONENT() (storage->delegate) // how to find delegate component
-
- #define COMPONENT_UPP_SELECT_ROOT() ImageCodec // root for Type's UPP_PREFIX and SELECT_PREFIX
-
- #include "Components.k.h" // StdComponent's .k.h
- #include "ImageCodec.k.h" // Type's .k.h
- #include "ComponentDispatchHelper.c" // make our dispatcher and cando
-
- // End Dispatch Stuff
- /************************************************************************************/
-
- // --------------------------------------------------------------------------------------
- // MULTIPLE BIT-DEPTH AND PIXEL FORMATS
- // For clarity/reuse sake, the drawing code is being kept separate from the component
- // interface code.
- // --------------------------------------------------------------------------------------
-
-
- // 16BE555
- #define EffectFilter16 EffectFilter16BE555
- #define srcIs16BE555 1
- #define dstIs16BE555 1
- #include "EffectFilter16.c"
- #undef EffectFilter16
- #undef srcIs16BE555
- #undef dstIs16BE555
-
- #if NON_MAC_PIXEL_FORMATS
- // 16LE555
- #define EffectFilter16 EffectFilter16LE555
- #define srcIs16LE555 1
- #define dstIs16LE555 1
- #include "EffectFilter16.c"
- #undef EffectFilter16
- #undef srcIs16LE555
- #undef dstIs16LE555
-
- // 16LE565
- #define EffectFilter16 EffectFilter16LE565
- #define srcIs16LE565 1
- #define dstIs16LE565 1
- #include "EffectFilter16.c"
- #undef EffectFilter16
- #undef srcIs16LE565
- #undef dstIs16LE565
-
- #endif
-
- // 32ARGB
- #define EffectFilter32 EffectFilter32ARGB
- #define srcIs32ARGB 1
- #define dstIs32ARGB 1
- #include "EffectFilter32.c"
- #undef EffectFilter32
- #undef srcIs32ARGB
- #undef dstIs32ARGB
- #if NON_MAC_PIXEL_FORMATS
- // 32BGRA
- #define EffectFilter32 EffectFilter32BGRA
- #define srcIs32BGRA 1
- #define dstIs32BGRA 1
- #include "EffectFilter32.c"
- #undef EffectFilter32
- #undef srcIs32BGRA
- #undef dstIs32BGRA
- // 32RGBA
- #define EffectFilter32 EffectFilter32RGBA
- #define srcIs32RGBA 1
- #define dstIs32RGBA 1
- #include "EffectFilter32.c"
- #undef EffectFilter32
- #undef srcIs32RGBA
- #undef dstIs32RGBA
- // 32ABGR
- #define EffectFilter32 EffectFilter32ABGR
- #define srcIs32ABGR 1
- #define dstIs32ABGR 1
- #include "EffectFilter32.c"
- #undef EffectFilter32
- #undef srcIs32ABGR
- #undef dstIs32ABGR
- #endif
-
- // --------------------------------------------------------------------------------------
- // INTERNAL ROUTINES
- // For clarity/reuse sake, the drawing code is being kept separate from the component
- // interface code.
- // --------------------------------------------------------------------------------------
-
-
- static OSErr RequestImageFormat(
- EffectGlobals* glob, // input: globals for rendering
- EffectSourcePtr source, // input: source to potentially convert
- short width, // input: desired width
- short height, // input: desired height
- OSType pixelFormat)// input: desired pixel format (depth & format)
- /*
- If the data is already in the requested height and depth, returns.
- Otherwise, calls decompression to get it into the format we can handle
- */
- {
- OSErr err = noErr;
- CDSequenceDataSourcePtr sourceData = source->source.image;
- ImageDescriptionHandle curDesc = (ImageDescriptionHandle) sourceData->dataDescription;
- ImageDescriptionHandle newDesc = nil;
- ImageDescriptionPtr dp;
-
- dp = *curDesc;
- if (
- (source->effectType == kEffectRawSource) &&
- ( ((dp->cType == kRawCodecType) && (dp->depth == (short)pixelFormat)) || ( dp->cType == pixelFormat) ) &&
-
- (dp->width == width) &&
- (dp->height == height))
- {
- /* already got what we need */
- return noErr;
- }
-
- // otherwise, call the ICM to convert to desired data format
- newDesc = (ImageDescriptionHandle) NewHandleClear(sizeof(ImageDescription));
- err = MemError();
-
- if (err == noErr)
- {
- short pixelSize = QTGetPixelSize(pixelFormat);
-
-
-
- dp = *newDesc;
- #if ! NON_MAC_PIXEL_FORMATS
-
- if ((pixelFormat >> 24) != 0) {
-
- // non-Mac format
-
- dp->cType = pixelFormat;
-
- dp->depth = pixelSize;
-
- } else {
-
- dp->cType = kRawCodecType;
-
- dp->depth = pixelFormat;
-
- }
-
- #else
-
- dp->cType = pixelFormat;
-
- dp->depth = pixelSize;
-
- #endif
-
- dp->width = width;
- dp->height = height;
- dp->clutID = -1;
-
- /* the source is a stacked effect - or one in a format we can't handle. */
- /* pass it off to the Generic Effect to convert */
- /* it to a normal source */
- err = ImageCodecEffectConvertEffectSourceToFormat(glob->target, source, newDesc);
-
- if (newDesc)
- {
- DisposeHandle((Handle) newDesc);
- }
- }
-
- return err;
-
- } // RequestImageFormat
-
- // --------------------------------------------------------------------------------------
- static long BlitterPreflight(BlitGlobals *glob, // input: globals for rendering
- short width, // input: width of data
- short height, // input: height of data
- long *depth) // input/output: depth of data
- {
- // *** CHANGE *** If your effect handles different bit depths, change this code to return
- // what bit depths you want.
-
- // our blitter can handle 16 and 32 bit deep -- otherwise, we request a change to 16 bit
- switch (*depth)
- {
- case 16:
- case 32:
- break;
-
- default:
- *depth = 16;
- break;
- }
- // *** END CHANGE ***
-
- // save away the actual depth we are running at
- glob->width = width;
- glob->height = height;
- glob->destDepth = *depth;
-
- return noErr;
-
- } // BlitterPreflight
-
- // --------------------------------------------------------------------------------------
- static long BlitterSetSource(EffectGlobals *glob, // input: our globals
- long sourceNumber, // input: source index to set
- EffectSourcePtr source) // input: source value
- {
- OSErr err = noErr;
-
- if (sourceNumber >= kMaxSources)
- {
- // too many sources for us to handle
- err = -1;
- }
- else
- {
- // a source we can handle, save it away
- err = RequestImageFormat(glob, source, glob->blitter.width, glob->blitter.height, glob->blitter.dstPixelFormat);
- if (err == noErr)
- {
- glob->blitter.sources[sourceNumber].src = source->source.image;
- }
- else
- {
- glob->blitter.sources[sourceNumber].src = nil;
- }
- }
-
- return (err);
-
- } // BlitterSetSource
-
-
- // --------------------------------------------------------------------------------------
- static long BlitterSetDest(BlitGlobals *glob, // input: our globals
- PixMap *dstPixMap, // input: pixels we will draw into
- Rect *dstRect) // input: area of pixels we will draw into
- {
- OSErr result = noErr;
- long offsetH,offsetV;
- char *baseAddr;
- OSType dstPixelFormat;
-
-
-
- dstPixelFormat = GETPIXMAPPIXELFORMAT(dstPixMap);
-
-
-
- glob->dstPixelFormat = dstPixelFormat;
-
-
-
-
- // *** CHANGE *** If your effect handles different bit depths, change this code
- /* adjust the destination baseaddress to be at the beginning of the desired rect */
- offsetH = (dstRect->left - dstPixMap->bounds.left);
- if (dstPixMap->pixelSize == 16)
- {
- offsetH <<= 1; /* 1 pixel = 2 bytes */
- }
- else
- {
- if (dstPixMap->pixelSize == 32)
- {
- offsetH <<= 2; /* 1 pixel = 4 bytes */
- }
- else
- {
- result = -1; /* a data format we can't handle */
- }
- }
- // *** END CHANGE ***
-
- offsetV = (dstRect->top - dstPixMap->bounds.top) * dstPixMap->rowBytes;
- baseAddr = dstPixMap->baseAddr + offsetH + offsetV;
-
- glob->dstBaseAddr = baseAddr;
- glob->dstRowBytes = dstPixMap->rowBytes;
-
- return result;
-
- } // BlitterSetDest
-
-
- // --------------------------------------------------------------------------------------
- static long BlitterRenderFrame(BlitGlobals *glob) // input: our globals
- {
- SInt8 mmuMode;
-
- // render with proper memory mode
- mmuMode = true32b;
- SwapMMUMode(&mmuMode);
-
- // convert data into base/size
- {
- short i;
-
- for (i = 0; i < kMaxSources; ++i)
- {
- if (glob->sources[i].src)
- {
- glob->sources[i].srcBaseAddr = glob->sources[i].src->dataPtr;
- glob->sources[i].srcRowBytes = glob->sources[i].src->dataSize / glob->height;
- }
- }
- }
-
- // *** CHANGE *** If your effect handles different bit depths, write other bit depth routines and
- // call them from here
-
- // do the actual render
- switch (glob->dstPixelFormat)
- {
- case k32ARGBPixelFormat:
- EffectFilter32ARGB(glob);
- break;
- #if NON_MAC_PIXEL_FORMATS
- case k32ABGRPixelFormat:
- EffectFilter32ABGR(glob); break;
- case k32BGRAPixelFormat: // we know how to do these pixel formats
- EffectFilter32BGRA(glob); break;
- case k32RGBAPixelFormat:
- EffectFilter32RGBA(glob); break;
- #endif
- case k16BE555PixelFormat:
- EffectFilter16BE555(glob);
- break;
- #if NON_MAC_PIXEL_FORMATS
- case k16LE565PixelFormat:
- EffectFilter16LE565(glob); break;
- case k16LE555PixelFormat:
- EffectFilter16LE555(glob); break;
- #endif
- }
- // *** END CHANGE ***
-
- SwapMMUMode(&mmuMode);
-
- return noErr;
-
- } // BlitterRenderFrame
-
-
- // --------------------------------------------------------------------------------------
- // COMPONENT ENTRY POINTS
- // --------------------------------------------------------------------------------------
-
-
- #define kNumPixelFormatsSupported 0x20
-
- pascal ComponentResult EffectsFrameOpen(EffectGlobals *glob, // input/output: our globals
- ComponentInstance self) // input: reference to ourself
- /*
- This is called once per instance of our component. Allocate our storage at
- this point. If we have any shared storage, we would check here to make sure
- it exists, else create it.
- */
- {
- ComponentResult result;
-
- result = noErr;
-
- // first, allocate our local storage
- if ((glob = (EffectGlobals*) NewPtrClear(sizeof(EffectGlobals)))==nil)
- {
- result = MemError();
- goto bail;
- }
-
- SetComponentInstanceStorage(self, (Handle) glob);
-
- // we are ourselves, and the current top of chain is us
- glob->self = self;
- glob->target = self;
- glob->wantedDestinationPixelTypeH = (OSType **) NewHandleClear(sizeof(OSType) * (kNumPixelFormatsSupported + 1));
-
- // open the generic effect, this will handle effects we can't handle ourselves
- result = OpenADefaultComponent(decompressorComponentType, kEffectGenericType, &glob->delegate);
- if (result)
- goto bail;
-
- // set up the target for the components below us
- EffectsFrameTarget(glob, self);
-
- bail:
- return(result);
-
- } // EffectsFrameOpen
-
-
- // --------------------------------------------------------------------------------------
- // Called each time an instance of our component is going away. Toss anything we allocated.
- pascal ComponentResult EffectsFrameClose(EffectGlobals *glob, // input: our globals
- ComponentInstance self) // input: reference to ourself
- {
- #pragma unused (self)
-
- if (glob)
- {
- /* *** CHANGE *** DISPOSE OF YOUR TWEENERS */
- DisposeTweenRecord(&glob->percentage);
-
- /* *** END CHANGE *** */
-
-
-
- DisposeTweenGlobals(&glob->tweenGlobals);
-
- CloseComponent(glob->delegate);
-
-
- DisposeHandle((Handle) glob->wantedDestinationPixelTypeH);
-
-
- DisposePtr((Ptr) glob);
- }
- return(noErr);
-
- } // EffectsFrameClose
-
-
- // --------------------------------------------------------------------------------------
-
- pascal ComponentResult EffectsFrameTarget(EffectGlobals *glob, // input: our globals
- ComponentInstance target) // input: reference to new top of chain
- /*
- Called when there is a new top of the calling chain. Remember that ourselves, and tell
- those below us as well.
- */
- {
- // remember who is top of chain
- glob->target = target;
-
- // and tell folks below us, too.
- ComponentSetTarget(glob->delegate, target);
-
- return(noErr);
-
- } // EffectsFrameTarget
-
-
- // --------------------------------------------------------------------------------------
-
- pascal ComponentResult EffectsFrameVersion(EffectGlobals *glob) // input: our globals
- /*
- Called to obtain the version of our component.
- */
- {
- #pragma unused (glob)
-
- return kDimmerEffectVersion;
-
- } // EffectsFrameVersion
-
-
- // --------------------------------------------------------------------------------------
- // Called to prepare for a sequence of frames.
- // Return in p->capabilities anything in particular your effect requires, such as
- // limitations on bitdepth.
- pascal long EffectsFrameEffectSetup(EffectGlobals *glob, // input: our globals
- CodecDecompressParams *p) // input: information about the thing being decompressed
-
- {
- CodecCapabilities *capabilities = p->capabilities;
- OSErr err;
- OSType *formats = *glob->wantedDestinationPixelTypeH;
- long wantedPixelSize = capabilities->wantedPixelSize;
- OSType dstPixelFormat;
-
- dstPixelFormat = GETPIXMAPPIXELFORMAT(&p->dstPixMap);
-
-
-
- switch (dstPixelFormat)
- {
- case k32ARGBPixelFormat:
- case k16BE555PixelFormat:
- #if NON_MAC_PIXEL_FORMATS
- case k32BGRAPixelFormat: // we know how to do these pixel formats
- case k32ABGRPixelFormat:
- case k32RGBAPixelFormat:
- case k16LE565PixelFormat:
- case k16LE555PixelFormat:
- #endif
- *formats++ = dstPixelFormat;
- break;
- default: // we prefer 16 over 32
- #if NON_MAC_PIXEL_FORMATS
- *formats++ = k16LE555PixelFormat;
- *formats++ = k16LE565PixelFormat;
- *formats++ = k32BGRAPixelFormat;
- *formats++ = k32RGBAPixelFormat;
- *formats++ = k32ABGRPixelFormat;
- #endif
- *formats++ = k16BE555PixelFormat;
- *formats++ = k32ARGBPixelFormat;
- break;
- }
-
-
-
- // NOTE: 0 marks the end of the format list
-
- *formats++ = 0;
-
-
- /* set up our blitter */
- err = BlitterPreflight(&glob->blitter,
- (*p->imageDescription)->width,
- (*p->imageDescription)->height,
- &wantedPixelSize);
-
- capabilities->wantedPixelSize = 0;
-
- p->wantedDestinationPixelTypes = glob->wantedDestinationPixelTypeH;
-
-
- return (err);
-
- } // EffectsFrameEffectSetup
-
- // --------------------------------------------------------------------------------------
-
- pascal void GetIntegrityParam (EffectGlobals* glob, CodecDecompressParams* p)
- {
- Ptr data = p->data;
- QTAtom atom;
- QTAtomID atomID = 1;
- long actSize;
- long temp;
- long i;
-
- // Find the 'sden' atom
- atom = QTFindChildByID((QTAtomContainer) &data,
- kParentAtomIsContainer,
- OSTypeConst('SrIn'),// The name of the parameter
- atomID, // The ID of the parameter
- nil);
-
- // Copy the parameter value from the atom
- if (QTCopyAtomDataToPtr((QTAtomContainer) &data, atom, false, sizeof(long),
- &temp, &actSize)!=noErr)
- {
- // If the copy failed, use a default value for this parameter
- ((glob->blitter).iIntegrity) = 10;
- } else {
- // Otherwise, the copy succeeded, so endian flip and store the parameter value
- ((glob->blitter).iIntegrity) = temp;
- }
-
- (glob->blitter).puiRandoms = (UInt8*)NewPtr (32768);
- if ((glob->blitter).puiRandoms == NULL) {
- DebugStr ("\ppuiRandoms is NULL!!!!");
- }
-
- for (i = 0; i < 32768; i++) {
- (glob->blitter).puiRandoms [ i ] = ((float)((UInt32)Random ()) * (float)temp) / 65535.0 * 4;
- if ((glob->blitter).puiRandoms [ i ] > (temp * 4)) {
- DebugStr ("\ppuiRandoms are wrong");
- }
- }
-
- (glob->blitter).puiBrightnessRoll = (UInt8*)NewPtr ((glob->blitter).height * 2);
- if ((glob->blitter).puiBrightnessRoll == NULL) {
- DebugStr ("\ppfBrightnessRoll is NULL!!!!");
- }
-
- for (i = 0; i < (glob->blitter).height * 2; i++) {
- double pi = 3.14159;
- double fResult;
- fResult = 0.5 - (0.5 * cos (2.0 * pi * (double)i / (double)((glob->blitter).height * 2)));
- fResult *= fResult;
- fResult *= fResult;
- fResult *= fResult;
- fResult = 0.2 - (0.2 * fResult);
- glob->blitter.puiBrightnessRoll [ i ] = ((double)fResult * (double)255.0);
- }
-
- glob->blitter.puiBRStart = glob->blitter.puiBrightnessRoll;
- glob->blitter.puiBREnd = glob->blitter.puiBrightnessRoll + glob->blitter.height;
- /* fDstGamma = (glob->blitter).fDstGamma;
-
- dstPixelFormat = GETPIXMAPPIXELFORMAT(&p->dstPixMap);
-
- if (dstPixelFormat == k16BE555PixelFormat) {
- for (i = 0; i < 32; i++) {
- (glob->blitter).pcDstGamma [ i ] = (UInt8)(pow (((double)i / 31.0), fDstGamma) * 31.0);
- }
- } else {
- for (i = 0; i < 256; i++) {
- (glob->blitter).pcDstGamma [ i ] = (UInt8)(pow (((double)i / 255.0), fDstGamma) * 255.0);
- }
- }*/
- }
-
- // ----------
- // Called for each frame, before the request to actually draw
- pascal long EffectsFrameEffectBegin(EffectGlobals *glob, // input: our globals
- CodecDecompressParams *p, // input: info about frame being drawn
- EffectsFrameParamsPtr effect) // input: info about this effect frame
- {
- OSErr err = noErr;
- EffectSourcePtr source;
- long numSources = 0;
- wide percentage;
-
- #if kMaxAsyncFrames > 0
- /* we can go async if we don't already have an effect scheduled */
- if (glob->asyncCount < kMaxAsyncFrames)
- {
- glob->asyncCount++;
- effect->doAsync = true;
- }
- #endif
-
- // dest changed?
- if (p->conditionFlags &
- (codecConditionNewClut+codecConditionFirstFrame+codecConditionNewDepth+codecConditionNewDestination+codecConditionNewTransform))
- {
- // re-scan the sources
- glob->majorSourceChangeSeed = 0;
-
- // re-read the parameters
- glob->frameNumber = 0;
-
- err = BlitterSetDest(&glob->blitter, &p->dstPixMap, &p->dstRect);
- if (err != noErr)
- goto bail;
-
- }
-
- // new sources? make note of them!
- if (p->majorSourceChangeSeed != glob->majorSourceChangeSeed)
- {
- // grab start of input chain for this effect
- source = effect->source;
-
- /* we can play with up to kMaxSources sources, so go get them */
- while (source != nil && numSources < kMaxSources)
- {
- /* now give that source to our blitter */
- err = BlitterSetSource(glob, numSources, source);
- if (err != noErr)
- goto bail;
-
- source = source->next;
- ++numSources;
- }
-
-
-
- glob->majorSourceChangeSeed = p->majorSourceChangeSeed;
- }
-
- /* if this is a new frame, or the same frame with a new length, get rid of our old parameters & tweeners */
- if ((effect->frameTime.frameNumber != glob->frameNumber) || (effect->frameTime.virtualDuration != glob->virtualDuration) )
- {
- /* *** CHANGE *** DISPOSE OF YOUR TWEENERS */
- DisposeTweenRecord(&glob->percentage);
-
- /* *** END CHANGE *** */
-
-
-
- DisposeTweenGlobals(&glob->tweenGlobals);
-
- glob->initialized = false;
- glob->frameNumber = effect->frameTime.frameNumber;
- glob->virtualDuration = effect->frameTime.virtualDuration;
- }
-
- // Read in effect parameters
- if (!glob->initialized)
- {
- Ptr data = p->data;
- OSErr err;
- long index = 1;
-
- err = InitializeTweenGlobals(&glob->tweenGlobals, p);
- if (err!=noErr)
- goto bail;
-
- /* *** CHANGE *** TIME TO READ IN PARAMETERS TO YOUR EFFECT:
- You can read any number of atoms you wish from the container. For example, you might have a
- 'star' (start) and 'end ' (end) value. They might be expressed as percentages, numbers, or other values.
- Or, you might have multiple atoms of type 'para' (param) which would be read in by calling
- QTFindChildByIndex with various index values. If you want to know how many parameters of a given
- type there are, call QTCountChildrenOfType. These parameters are specific to your particular effect,
- and will need to be placed there by whoever is authoring the title.
-
- If you require parameters, and they aren't there, return an error. If you can default the values
- if they are missing, do so and continue. In general, I'd recommend having a default case unless
- you really are unable to implement it for a technical reason.
-
- These parameters are those that apply to the effect itself. Later, we'll translate some of these parameters
- into how they relate to *where* in the effect we are. For example, an effect that runs from a starting
- percentage of 10 to an ending percentage of 90 will have 10 and 90 as parameters here.
- */
-
- /* make our tweener, return if we already have it */
- err = CreateTweenRecord(&glob->tweenGlobals, &glob->percentage,
- kParameterUsagePercent, 1,
- sizeof(Fixed), kTweenTypeFixed, (void*)0, (void*)fixed1,
- effect->frameTime.virtualDuration);
- if (err!=noErr)
- goto bail;
-
- GetIntegrityParam (glob, p);
-
-
- /* *** END CHANGE *** */
-
-
-
- glob->initialized = true;
- }
-
- /* determine the amount we are along the tween via the current time - start time */
- percentage = effect->frameTime.value;
- CompSub(&effect->frameTime.virtualStartTime, &percentage);
-
-
- /* Tween our parameters and get the current value for this frame, prepare to render
- it when the RenderFrame happens. */
- if (err == noErr)
- {
- Fixed thePercentage;
-
- /* ***** CHANGE TO TWEEN YOUR EFFECTS PARAMETERS */
-
- if (glob->percentage.tween)
- QTDoTween(glob->percentage.tween, percentage.lo, glob->percentage.tweenData, nil, nil, nil );
-
- thePercentage = **(Fixed**)(glob->percentage.tweenData);
- // If we are before the half-way point of this transition, we should
- // be fading the first source to black
- if (thePercentage < fixed1/2)
- {
- (glob->blitter).direction = 1;
- (glob->blitter).dimValue = FixedToInt(FixMul(IntToFixed(512), thePercentage));
- }
- // Otherwise, we are fading up onto the new source
- else
- {
- (glob->blitter).direction = 0;
- (glob->blitter).dimValue = FixedToInt(FixMul(IntToFixed(512), thePercentage)) - 255;
- }
-
- (glob->blitter).puiBrightnessRoll++;
- if ((glob->blitter).puiBrightnessRoll > (glob->blitter).puiBREnd) {
- (glob->blitter).puiBrightnessRoll = (glob->blitter).puiBRStart;
- }
-
- /* ***** END CHANGE */
- }
-
- if (glob->tweenGlobals.atLeastOneTweener)
- {
- // this effect runs constantly
- p->needUpdateOnTimeChange = true;
- p->needUpdateOnSourceChange = false;
- }
- else
- {
- // this effect only needs to run when the sources actually change
- p->needUpdateOnTimeChange = true; //false;
- p->needUpdateOnSourceChange = false; //true;
- }
-
-
- // EXCEPTION HANDLING
- bail:
- #if kMaxAsyncFrames > 0
- // if we didn't queue the frame, then remove it from used list
- if (err != noErr)
- glob->asyncCount--;
- #endif
-
- return err;
-
- } // EffectsFrameEffectBegin
-
-
- // --------------------------------------------------------------------------------------
- pascal long EffectsFrameEffectRenderFrame(EffectGlobals *glob, // input: our globals
- EffectsFrameParamsPtr effect) // input: effect frame to be rendered
- /*
- Start rendering of the given frame.
- */
- {
- #pragma unused (effect)
-
- /* render the frame */
- BlitterRenderFrame(&glob->blitter);
-
- #if kMaxAsyncFrames > 0
- glob->asyncCount--;
- #endif
-
- return noErr;
-
- } // EffectsFrameEffectRenderFrame
-
-
- // --------------------------------------------------------------------------------------
- pascal long EffectsFrameEffectCancel(EffectGlobals *glob, // input: our globals
- EffectsFrameParamsPtr effect) // input: effect frame to be canceled
- /*
- Halt rendering of the given frame, even if it is only partially completed.
- */
- {
- #pragma unused (effect)
- #pragma unused (glob)
-
- #if kMaxAsyncFrames > 0
- glob->asyncCount--;
- #endif
-
- return noErr;
-
- } // EffectsFrameEffectCancel
-
-
- // ----------------------------------------------------------------------------------------
-
- pascal ComponentResult EffectsFrameGetCodecInfo(EffectGlobals *glob,
- CodecInfo *info)
- /*
- * CDGetCodecInfo allows us to return information about ourselves to the codec manager.
- *
- * There will be a tool for determining appropriate values for the accuracy, speed
- * and level information. For now we estimate with scientific wild guessing.
- *
- * The info is stored as a resource in the same file with our component.
- */
- {
- OSErr err = noErr;
-
- if (info == nil)
- {
- err = paramErr;
- }
- else
- {
- CodecInfo **tempCodecInfo;
-
- err = GetComponentResource((Component) glob->self,
- codecInfoResourceType,
- kEffectcdciRes,
- (Handle *) &tempCodecInfo);
- if (err == noErr)
- {
- *info = **tempCodecInfo;
- DisposeHandle((Handle) tempCodecInfo);
- }
- }
-
- return err;
-
- } // EffectsFrameGetCodecInfo
-
-
- // ---------------------------------------------------------------------------------------------------------------------------
- pascal ComponentResult EffectsFrameGetParameterListHandle(EffectGlobals *glob, // input: our globals
- Handle *theHandle) // output: the parameter description for this effect
- {
- OSErr err = noErr;
-
- err = GetComponentResource((Component) glob->self,
- FOUR_CHAR_CODE('atms'),
- kEffectatmsRes,
- theHandle);
-
- return(err);
-
- } // EffectsFrameGetParameterListHandle
-
- // ----------------------------------------------------------------------------------------
- pascal long EffectsFrameEffectGetSpeed(EffectGlobals * glob, QTAtomContainer parameters, Fixed *pFPS)
- {
- #pragma unused (glob, parameters)
-
- if (pFPS)
- *pFPS = IntToFixed(30);
-
- return noErr;
-
- } // EffectsFrameEffectGetSpeed
-
-
-